/**
 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "optimizer/ir/datatype.h"
#include "unit_ecma_test.h"

namespace ark::compiler {
class IrBuilderTest : public AsmTest {
public:
    IrBuilderTest() = default;
};

TEST_F(IrBuilderTest, CompareAnyType)
{
    // no crash.
    auto graph = CreateGraphDynWithDefaultRuntime();
    GRAPH(graph)
    {
        PARAMETER(0, 0).any();

        BASIC_BLOCK(2, -1)
        {
            INST(2, Opcode::CompareAnyType).b().AnyType(AnyBaseType::ECMASCRIPT_INT_TYPE).Inputs(0);
            INST(3, Opcode::Return).s32().Inputs(2);
        }
    }

    const CompareAnyTypeInst *cati = INS(2).CastToCompareAnyType();

    ASSERT_TRUE(cati != nullptr);
    EXPECT_TRUE(cati->GetInputType(0) == DataType::Type::ANY);
    EXPECT_TRUE(cati->GetType() == DataType::BOOL);
    EXPECT_TRUE(cati->GetAnyType() == AnyBaseType::ECMASCRIPT_INT_TYPE);
}

TEST_F(IrBuilderTest, CastAnyTypeValue)
{
    // no crash.
    auto graph = CreateGraphDynWithDefaultRuntime();
    GRAPH(graph)
    {
        PARAMETER(0, 0).any();

        BASIC_BLOCK(2, -1)
        {
            INST(2, Opcode::CastAnyTypeValue).f64().AnyType(AnyBaseType::ECMASCRIPT_DOUBLE_TYPE).Inputs(0);
            INST(3, Opcode::Return).f64().Inputs(2);
        }
    }

    const CastAnyTypeValueInst *catvi = INS(2).CastToCastAnyTypeValue();

    ASSERT_TRUE(catvi != nullptr);
    EXPECT_TRUE(catvi->GetInputType(0) == DataType::Type::ANY);
    EXPECT_TRUE(catvi->GetDeducedType() == DataType::Type::FLOAT64);
    EXPECT_TRUE(catvi->GetAnyType() == AnyBaseType::ECMASCRIPT_DOUBLE_TYPE);
}

TEST_F(IrBuilderTest, CastValueToAnyType)
{
    // no crash.
    auto graph = CreateGraphDynStubWithDefaultRuntime();
    GRAPH(graph)
    {
        PARAMETER(0, 0).i32();

        BASIC_BLOCK(2, -1)
        {
            INST(2, Opcode::CastValueToAnyType).any().AnyType(AnyBaseType::ECMASCRIPT_INT_TYPE).Inputs(0);
            INST(3, Opcode::Return).any().Inputs(2);
        }
    }

    const CastValueToAnyTypeInst *cvai = INS(2).CastToCastValueToAnyType();

    ASSERT_TRUE(cvai != nullptr);
    EXPECT_TRUE(cvai->GetInputType(0) == DataType::Type::INT32);
    EXPECT_TRUE(cvai->GetType() == DataType::Type::ANY);
    EXPECT_TRUE(cvai->GetAnyType() == AnyBaseType::ECMASCRIPT_INT_TYPE);
}

}  // namespace ark::compiler
